home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / dist-packages / ufw / backend_iptables.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  23.9 KB  |  1,002 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import os
  5. import re
  6. import sys
  7. import tempfile
  8. from ufw.common import UFWError, UFWRule, config_dir, state_dir, prefix_dir
  9. from ufw.util import warn, debug, msg, cmd, cmd_pipe
  10. import ufw.backend as ufw
  11.  
  12. class UFWBackendIptables(ufw.backend.UFWBackend):
  13.     
  14.     def __init__(self, d):
  15.         self.comment_str = '# ' + ufw.common.programName + '_comment #'
  16.         files = { }
  17.         files['rules'] = os.path.join(state_dir, 'user.rules')
  18.         files['before_rules'] = os.path.join(config_dir, 'ufw/before.rules')
  19.         files['after_rules'] = os.path.join(config_dir, 'ufw/after.rules')
  20.         files['rules6'] = os.path.join(state_dir, 'user6.rules')
  21.         files['before6_rules'] = os.path.join(config_dir, 'ufw/before6.rules')
  22.         files['after6_rules'] = os.path.join(config_dir, 'ufw/after6.rules')
  23.         files['init'] = os.path.join(prefix_dir, 'share/ufw/ufw-init')
  24.         ufw.backend.UFWBackend.__init__(self, 'iptables', d, files)
  25.         self.chains = {
  26.             'before': [],
  27.             'user': [],
  28.             'after': [],
  29.             'misc': [] }
  30.         for ver in [
  31.             '4',
  32.             '6']:
  33.             chain_prefix = 'ufw'
  34.             if ver == '6':
  35.                 if self.use_ipv6():
  36.                     chain_prefix += ver
  37.                 elif ver == '6':
  38.                     continue
  39.                 
  40.             
  41.             for loc in [
  42.                 'before',
  43.                 'user',
  44.                 'after']:
  45.                 for target in [
  46.                     'input',
  47.                     'output',
  48.                     'forward']:
  49.                     chain = '%s-%s-logging-%s' % (chain_prefix, loc, target)
  50.                     self.chains[loc].append(chain)
  51.                 
  52.             
  53.             self.chains['misc'].append(chain_prefix + '-logging-deny')
  54.             self.chains['misc'].append(chain_prefix + '-logging-allow')
  55.         
  56.  
  57.     
  58.     def get_default_policy(self, primary = 'input'):
  59.         '''Get current policy'''
  60.         policy = 'default_' + primary + '_policy'
  61.         rstr = ''
  62.         if self.defaults[policy] == 'accept':
  63.             rstr = 'allow'
  64.         elif self.defaults[policy] == 'reject':
  65.             rstr = 'reject'
  66.         else:
  67.             rstr = 'deny'
  68.         return rstr
  69.  
  70.     
  71.     def get_default_application_policy(self):
  72.         '''Get current policy'''
  73.         rstr = _('New profiles:')
  74.         if self.defaults['default_application_policy'] == 'accept':
  75.             rstr += ' allow'
  76.         elif self.defaults['default_application_policy'] == 'drop':
  77.             rstr += ' deny'
  78.         elif self.defaults['default_application_policy'] == 'reject':
  79.             rstr += ' reject'
  80.         else:
  81.             rstr += ' skip'
  82.         return rstr
  83.  
  84.     
  85.     def set_default_policy(self, policy):
  86.         '''Sets default policy of firewall'''
  87.         if not self.dryrun:
  88.             if policy != 'allow' and policy != 'deny' and policy != 'reject':
  89.                 err_msg = _("Unsupported policy '%s'") % policy
  90.                 raise UFWError(err_msg)
  91.             policy != 'reject'
  92.             old_log_str = ''
  93.             new_log_str = ''
  94.             if policy == 'allow':
  95.                 self.set_default(self.files['defaults'], 'DEFAULT_INPUT_POLICY', '"ACCEPT"')
  96.                 old_log_str = 'UFW BLOCK'
  97.                 new_log_str = 'UFW ALLOW'
  98.             elif policy == 'reject':
  99.                 self.set_default(self.files['defaults'], 'DEFAULT_INPUT_POLICY', '"REJECT"')
  100.                 old_log_str = 'UFW ALLOW'
  101.                 new_log_str = 'UFW BLOCK'
  102.             else:
  103.                 self.set_default(self.files['defaults'], 'DEFAULT_INPUT_POLICY', '"DROP"')
  104.                 old_log_str = 'UFW ALLOW'
  105.                 new_log_str = 'UFW BLOCK'
  106.             pat = re.compile('' + old_log_str)
  107.             for f in [
  108.                 self.files['after_rules'],
  109.                 self.files['after6_rules']]:
  110.                 
  111.                 try:
  112.                     fns = ufw.util.open_files(f)
  113.                 except Exception:
  114.                     raise 
  115.  
  116.                 fd = fns['tmp']
  117.                 for line in fns['orig']:
  118.                     if pat.search(line):
  119.                         os.write(fd, pat.sub(new_log_str, line))
  120.                         continue
  121.                     os.write(fd, line)
  122.                 
  123.                 ufw.util.close_files(fns)
  124.             
  125.         
  126.         rstr = _("Default policy changed to '%s'\n") % policy
  127.         rstr += _('(be sure to update your rules accordingly)')
  128.         return rstr
  129.  
  130.     
  131.     def get_running_raw(self):
  132.         '''Show current running status of firewall'''
  133.         if self.dryrun:
  134.             out = '> ' + _('Checking raw iptables\n')
  135.             out += '> ' + _('Checking raw ip6tables\n')
  136.             return out
  137.         err_msg = _('problem running')
  138.         out = 'IPV4:\n'
  139.         for table in [
  140.             'filter',
  141.             'nat',
  142.             'mangle',
  143.             'raw']:
  144.             (rc, tmp) = cmd([
  145.                 'iptables',
  146.                 '-L',
  147.                 '-n',
  148.                 '-v',
  149.                 '-x',
  150.                 '-t',
  151.                 table])
  152.             out += tmp
  153.             if rc != 0:
  154.                 raise UFWError(out)
  155.             rc != 0
  156.         
  157.         out += '\n\nIPV6:\n'
  158.         for table in [
  159.             'filter',
  160.             'mangle',
  161.             'raw']:
  162.             (rc, tmp) = cmd([
  163.                 'ip6tables',
  164.                 '-L',
  165.                 '-n',
  166.                 '-v',
  167.                 '-x',
  168.                 '-t',
  169.                 table])
  170.             out += tmp
  171.             if rc != 0:
  172.                 raise UFWError(out)
  173.             rc != 0
  174.         
  175.         return out
  176.  
  177.     
  178.     def get_status(self, verbose = False, show_count = False):
  179.         '''Show ufw managed rules'''
  180.         out = ''
  181.         out6 = ''
  182.         if self.dryrun:
  183.             out = '> ' + _('Checking iptables\n')
  184.             if self.use_ipv6():
  185.                 out += '> ' + _('Checking ip6tables\n')
  186.             
  187.             return out
  188.         (rc, out) = cmd([
  189.             'iptables',
  190.             '-L',
  191.             'ufw-user-input',
  192.             '-n'])
  193.         if rc != 0:
  194.             return _('Status: inactive')
  195.         err_msg = _('problem running')
  196.         if out == '' and out6 == '':
  197.             return _('Status: active')
  198.         str = ''
  199.         rules = self.rules + self.rules6
  200.         count = 1
  201.         app_rules = { }
  202.         for r in rules:
  203.             location = { }
  204.             tuple = ''
  205.             show_proto = True
  206.             if not verbose:
  207.                 pass
  208.             for loc in [
  209.                 'dst',
  210.                 'src']:
  211.                 location[loc] = ''
  212.                 port = ''
  213.                 tmp = ''
  214.                 if loc == 'dst':
  215.                     tmp = r.dst
  216.                     if not verbose and r.dapp != '':
  217.                         port = r.dapp
  218.                         if r.v6 and tmp == '::/0':
  219.                             port += ' (v6)'
  220.                         
  221.                     else:
  222.                         port = r.dport
  223.                 else:
  224.                     tmp = r.src
  225.                     if not verbose and r.sapp != '':
  226.                         port = r.sapp
  227.                         if r.v6 and tmp == '::/0':
  228.                             port += ' (v6)'
  229.                         
  230.                     else:
  231.                         port = r.sport
  232.                 if tmp != '0.0.0.0/0' and tmp != '::/0':
  233.                     location[loc] = tmp
  234.                 
  235.                 if port != 'any':
  236.                     if location[loc] == '':
  237.                         location[loc] = port
  238.                     else:
  239.                         location[loc] += ' ' + port
  240.                     if show_proto and r.protocol != 'any':
  241.                         location[loc] += '/' + r.protocol
  242.                     
  243.                     if verbose:
  244.                         if loc == 'dst' and r.dapp != '':
  245.                             location[loc] += ' (%s' % r.dapp
  246.                             if r.v6 and tmp == '::/0':
  247.                                 location[loc] += ' (v6)'
  248.                             
  249.                             location[loc] += ')'
  250.                         
  251.                         if loc == 'src' and r.sapp != '':
  252.                             location[loc] += ' (%s' % r.sapp
  253.                             if r.v6 and tmp == '::/0':
  254.                                 location[loc] += ' (v6)'
  255.                             
  256.                             location[loc] += ')'
  257.                         
  258.                     
  259.                 
  260.                 if port == 'any':
  261.                     if tmp == '0.0.0.0/0' or tmp == '::/0':
  262.                         location[loc] = 'Anywhere'
  263.                         if show_proto and r.protocol != 'any' and r.dst == r.src and r.dport == r.sport:
  264.                             location[loc] += '/' + r.protocol
  265.                         
  266.                         if tmp == '::/0':
  267.                             location[loc] += ' (v6)'
  268.                         
  269.                     elif show_proto and r.protocol != 'any' and r.dport == r.sport:
  270.                         location[loc] += '/' + r.protocol
  271.                     
  272.                 r.dport == r.sport
  273.             
  274.             if show_count:
  275.                 str += '[%2d] ' % count
  276.             
  277.             log_str = ''
  278.             if r.logtype:
  279.                 log_str = ' (%s)' % r.logtype.lower()
  280.             
  281.             str += '%-26s %-8s%s%s\n' % (location['dst'], r.action.upper(), location['src'], log_str)
  282.             count += 1
  283.         
  284.         if str != '':
  285.             header = '\n\n'
  286.             if show_count:
  287.                 header += '     '
  288.             
  289.             header += '%-26s %-8s%s\n' % (_('To'), _('Action'), _('From'))
  290.             if show_count:
  291.                 header += '     '
  292.             
  293.             header += '%-26s %-8s%s\n' % (_('--'), _('------'), _('----'))
  294.             str = header + str
  295.         
  296.         if verbose:
  297.             (level, logging_str) = self.get_loglevel()
  298.             policy_str = _('Default: %s') % self.get_default_policy()
  299.             app_policy_str = self.get_default_application_policy()
  300.             return _('Status: active') + '\n%s\n%s\n%s%s' % (logging_str, policy_str, app_policy_str, str)
  301.         return _('Status: active') + '%s' % str
  302.  
  303.     
  304.     def stop_firewall(self):
  305.         '''Stops the firewall'''
  306.         err_msg = _('problem running')
  307.         if self.dryrun:
  308.             msg('> ' + _('running ufw-init'))
  309.         else:
  310.             (rc, out) = cmd([
  311.                 self.files['init'],
  312.                 'force-stop'])
  313.             if rc != 0:
  314.                 raise UFWError(err_msg + ' ufw-init')
  315.             rc != 0
  316.  
  317.     
  318.     def start_firewall(self):
  319.         '''Starts the firewall'''
  320.         err_msg = _('problem running')
  321.         if self.dryrun:
  322.             msg('> ' + _('running ufw-init'))
  323.         else:
  324.             (rc, out) = cmd([
  325.                 self.files['init'],
  326.                 'start'])
  327.             if rc != 0:
  328.                 raise UFWError(err_msg + ' ufw-init')
  329.             rc != 0
  330.             if not self.defaults.has_key('loglevel') or self.defaults['loglevel'] not in self.loglevels.keys():
  331.                 
  332.                 try:
  333.                     self.set_loglevel('low')
  334.                 err_msg = _('Could not set LOGLEVEL')
  335.                 raise UFWError(err_msg)
  336.  
  337.             else:
  338.                 
  339.                 try:
  340.                     self.update_logging(self.defaults['loglevel'])
  341.                 except:
  342.                     err_msg = _('Could not load logging rules')
  343.                     raise UFWError(err_msg)
  344.  
  345.  
  346.     
  347.     def _need_reload(self, v6):
  348.         '''Check if all chains exist'''
  349.         if self.dryrun:
  350.             return False
  351.         prefix = 'ufw'
  352.         exe = 'iptables'
  353.         if v6:
  354.             prefix = 'ufw6'
  355.             exe = 'ip6tables'
  356.         
  357.         for chain in [
  358.             'input',
  359.             'output',
  360.             'forward',
  361.             'limit',
  362.             'limit-accept']:
  363.             if v6:
  364.                 if chain == 'limit' or chain == 'limit-accept':
  365.                     continue
  366.                 
  367.             (rc, out) = cmd([
  368.                 exe,
  369.                 '-n',
  370.                 '-L',
  371.                 prefix + '-user-' + chain])
  372.             if rc != 0:
  373.                 debug('_need_reload: forcing reload')
  374.                 return True
  375.         
  376.         return False
  377.  
  378.     
  379.     def _reload_user_rules(self):
  380.         '''Reload firewall rules file'''
  381.         err_msg = _('problem running')
  382.         if self.dryrun:
  383.             msg('> | iptables-restore')
  384.             if self.use_ipv6():
  385.                 msg('> | ip6tables-restore')
  386.             
  387.         elif self._is_enabled():
  388.             
  389.             try:
  390.                 for c in self.chains['user']:
  391.                     self._chain_cmd(c, [
  392.                         '-F',
  393.                         c])
  394.                     self._chain_cmd(c, [
  395.                         '-Z',
  396.                         c])
  397.             except:
  398.                 raise UFWError(err_msg)
  399.  
  400.             (rc, out) = cmd_pipe([
  401.                 'cat',
  402.                 self.files['rules']], [
  403.                 'iptables-restore',
  404.                 '-n'])
  405.             if rc != 0:
  406.                 raise UFWError(err_msg + ' iptables')
  407.             rc != 0
  408.             if self.use_ipv6():
  409.                 (rc, out) = cmd_pipe([
  410.                     'cat',
  411.                     self.files['rules6']], [
  412.                     'ip6tables-restore',
  413.                     '-n'])
  414.                 if rc != 0:
  415.                     raise UFWError(err_msg + ' ip6tables')
  416.                 rc != 0
  417.             
  418.         
  419.  
  420.     
  421.     def _get_rules_from_formatted(self, frule, prefix):
  422.         '''Return list of iptables rules appropriate for sending'''
  423.         snippets = []
  424.         pat_proto = re.compile('-p all ')
  425.         pat_port = re.compile('port ')
  426.         pat_reject = re.compile('-j (REJECT(_log(-all)?)?)')
  427.         if pat_proto.search(frule):
  428.             if pat_port.search(frule):
  429.                 if pat_reject.search(frule):
  430.                     snippets.append(pat_proto.sub('-p tcp ', pat_reject.sub('-j \\1 --reject-with tcp-reset ', frule)))
  431.                 else:
  432.                     snippets.append(pat_proto.sub('-p tcp ', frule))
  433.                 snippets.append(pat_proto.sub('-p udp ', frule))
  434.             else:
  435.                 snippets.append(pat_proto.sub('', frule))
  436.         else:
  437.             snippets.append(frule)
  438.         pat_log = re.compile('(.*)-j ([A-Z]+)_log(-all)?(.*)')
  439.         pat_logall = re.compile('-j [A-Z]+_log-all')
  440.         pat_chain = re.compile('(-A|-D) ([a-zA-Z0-9\\-]+)')
  441.         limit_args = '-m limit --limit 3/min --limit-burst 10'
  442.         for i, s in enumerate(snippets):
  443.             if pat_log.search(s):
  444.                 policy = pat_log.sub('\\2', s).strip()
  445.                 if policy.lower() == 'accept':
  446.                     policy = 'ALLOW'
  447.                 elif policy.lower() == 'limit':
  448.                     policy = 'LIMIT'
  449.                 else:
  450.                     policy = 'BLOCK'
  451.                 lstr = '%s -j LOG --log-prefix "[UFW %s] "' % (limit_args, policy)
  452.                 if not pat_logall.search(s):
  453.                     lstr = '-m state --state NEW ' + lstr
  454.                 
  455.                 snippets[i] = pat_log.sub('\\1-j \\2\\4', s)
  456.                 snippets.insert(i, pat_log.sub('\\1-j ' + prefix + '-user-logging-input', s))
  457.                 snippets.insert(i, pat_chain.sub('\\1 ' + prefix + '-user-logging-input', pat_log.sub('\\1-j RETURN', s)))
  458.                 snippets.insert(i, pat_chain.sub('\\1 ' + prefix + '-user-logging-input', pat_log.sub('\\1' + lstr, s)))
  459.                 continue
  460.         
  461.         pat_limit = re.compile(' -j LIMIT')
  462.         for i, s in enumerate(snippets):
  463.             if pat_limit.search(s):
  464.                 tmp1 = pat_limit.sub(' -m state --state NEW -m recent --set', s)
  465.                 tmp2 = pat_limit.sub(' -m state --state NEW -m recent' + ' --update --seconds 30 --hitcount 6' + ' -j ' + prefix + '-user-limit', s)
  466.                 tmp3 = pat_limit.sub(' -j ' + prefix + '-user-limit-accept', s)
  467.                 snippets[i] = tmp3
  468.                 snippets.insert(i, tmp2)
  469.                 snippets.insert(i, tmp1)
  470.                 continue
  471.         
  472.         return snippets
  473.  
  474.     
  475.     def _get_lists_from_formatted(self, frule, prefix):
  476.         '''Return list of iptables rules appropriate for sending as arguments
  477.            to cmd()
  478.         '''
  479.         snippets = []
  480.         str_snippets = self._get_rules_from_formatted(frule, prefix)
  481.         pat = re.compile('(.*) --log-prefix (".* ")(.*)')
  482.         for i, s in enumerate(str_snippets):
  483.             snippets.append(pat.sub('\\1', s).split())
  484.             if pat.match(s):
  485.                 snippets[i].append('--log-prefix')
  486.                 snippets[i].append(pat.sub('\\2', s).replace('"', ''))
  487.                 snippets[i] += pat.sub('\\3', s).split()
  488.                 continue
  489.         
  490.         return snippets
  491.  
  492.     
  493.     def _read_rules(self):
  494.         '''Read in rules that were added by ufw.'''
  495.         rfns = [
  496.             self.files['rules']]
  497.         if self.use_ipv6():
  498.             rfns.append(self.files['rules6'])
  499.         
  500.         for f in rfns:
  501.             
  502.             try:
  503.                 orig = ufw.util.open_file_read(f)
  504.             except Exception:
  505.                 err_msg = _("Couldn't open '%s' for reading") % f
  506.                 raise UFWError(err_msg)
  507.  
  508.             pat_tuple = re.compile('^### tuple ###\\s*')
  509.             for line in orig:
  510.                 if pat_tuple.match(line):
  511.                     tuple = pat_tuple.sub('', line)
  512.                     tmp = re.split('\\s+', tuple.strip())
  513.                 None if len(tmp) != 6 and len(tmp) != 8 else f == self.files['rules6']
  514.             
  515.             orig.close()
  516.         
  517.  
  518.     
  519.     def _write_rules(self, v6 = False):
  520.         '''Write out new rules to file to user chain file'''
  521.         rules_file = self.files['rules']
  522.         if v6:
  523.             rules_file = self.files['rules6']
  524.         
  525.         
  526.         try:
  527.             fns = ufw.util.open_files(rules_file)
  528.         except Exception:
  529.             raise 
  530.  
  531.         chain_prefix = 'ufw'
  532.         rules = self.rules
  533.         if v6:
  534.             chain_prefix = 'ufw6'
  535.             rules = self.rules6
  536.         
  537.         if self.dryrun:
  538.             fd = sys.stdout.fileno()
  539.         else:
  540.             fd = fns['tmp']
  541.         os.write(fd, '*filter\n')
  542.         os.write(fd, ':' + chain_prefix + '-user-input - [0:0]\n')
  543.         os.write(fd, ':' + chain_prefix + '-user-output - [0:0]\n')
  544.         os.write(fd, ':' + chain_prefix + '-user-forward - [0:0]\n')
  545.         if chain_prefix == 'ufw':
  546.             os.write(fd, ':' + chain_prefix + '-user-limit - [0:0]\n')
  547.             os.write(fd, ':' + chain_prefix + '-user-limit-accept - [0:0]\n')
  548.         
  549.         os.write(fd, '### RULES ###\n')
  550.         for r in rules:
  551.             action = r.action
  552.             if r.logtype != '':
  553.                 action += '_' + r.logtype
  554.             
  555.             if r.dapp == '' and r.sapp == '':
  556.                 os.write(fd, '\n### tuple ### %s %s %s %s %s %s\n' % (action, r.protocol, r.dport, r.dst, r.sport, r.src))
  557.             else:
  558.                 pat_space = re.compile(' ')
  559.                 dapp = '-'
  560.                 if r.dapp:
  561.                     dapp = pat_space.sub('%20', r.dapp)
  562.                 
  563.                 sapp = '-'
  564.                 if r.sapp:
  565.                     sapp = pat_space.sub('%20', r.sapp)
  566.                 
  567.                 os.write(fd, '\n### tuple ### %s %s %s %s %s %s %s %s\n' % (action, r.protocol, r.dport, r.dst, r.sport, r.src, dapp, sapp))
  568.             rule_str = '-A ' + chain_prefix + '-user-input ' + r.format_rule() + '\n'
  569.             for s in self._get_rules_from_formatted(rule_str, chain_prefix):
  570.                 os.write(fd, s)
  571.             
  572.         
  573.         os.write(fd, '\n### END RULES ###\n')
  574.         if chain_prefix == 'ufw':
  575.             os.write(fd, '-A ' + chain_prefix + '-user-limit -m limit ' + '--limit 3/minute -j LOG --log-prefix ' + '"[UFW LIMIT BLOCK] "\n')
  576.             os.write(fd, '-A ' + chain_prefix + '-user-limit -j REJECT\n')
  577.             os.write(fd, '-A ' + chain_prefix + '-user-limit-accept -j ACCEPT\n')
  578.         
  579.         os.write(fd, 'COMMIT\n')
  580.         if self.dryrun:
  581.             ufw.util.close_files(fns, False)
  582.         else:
  583.             ufw.util.close_files(fns)
  584.  
  585.     
  586.     def set_rule(self, rule, allow_reload = True):
  587.         '''Updates firewall with rule by:
  588.         * appending the rule to the chain if new rule and firewall enabled
  589.         * deleting the rule from the chain if found and firewall enabled
  590.         * inserting the rule if possible and firewall enabled
  591.         * updating user rules file
  592.         * reloading the user rules file if rule is modified
  593.         '''
  594.         rstr = ''
  595.         if rule.v6:
  596.             if not self.use_ipv6():
  597.                 err_msg = _('Adding IPv6 rule failed: IPv6 not enabled')
  598.                 raise UFWError(err_msg)
  599.             self.use_ipv6()
  600.             if rule.action == 'limit':
  601.                 return _("Skipping unsupported IPv6 '") + '%s' % rule.action + _("' rule")
  602.         
  603.         if rule.multi and rule.protocol != 'udp' and rule.protocol != 'tcp':
  604.             err_msg = _("Must specify 'tcp' or 'udp' with multiple ports")
  605.             raise UFWError(err_msg)
  606.         rule.protocol != 'tcp'
  607.         newrules = []
  608.         found = False
  609.         modified = False
  610.         delete = False
  611.         rules = self.rules
  612.         position = rule.position
  613.         if rule.v6:
  614.             if self.iptables_version < '1.4':
  615.                 if rule.dapp != '' or rule.sapp != '':
  616.                     return _('Skipping IPv6 application rule. Need at least iptables 1.4')
  617.                 rules = self.rules6
  618.             
  619.         if position < 0 or position > len(rules):
  620.             err_msg = _("Invalid position '%d'") % position
  621.             raise UFWError(err_msg)
  622.         position > len(rules)
  623.         if position > 0 and rule.remove:
  624.             err_msg = _('Cannot specify insert and delete')
  625.             raise UFWError(err_msg)
  626.         rule.remove
  627.         if position > len(rules):
  628.             err_msg = _("Cannot insert rule at position '%d'") % position
  629.             raise UFWError(err_msg)
  630.         position > len(rules)
  631.         
  632.         try:
  633.             rule.normalize()
  634.         except Exception:
  635.             raise 
  636.  
  637.         count = 1
  638.         inserted = False
  639.         matches = 0
  640.         last = ('', '', '', '')
  641.         for r in rules:
  642.             
  643.             try:
  644.                 r.normalize()
  645.             except Exception:
  646.                 raise 
  647.  
  648.             current = (r.dst, r.src, r.dapp, r.sapp)
  649.             if count == position:
  650.                 if not last[2] == '' and last[3] == '' or count > 1:
  651.                     if current[2] == '' or current[3] == '' or last != current:
  652.                         inserted = True
  653.                         newrules.append(rule)
  654.                         last = ('', '', '', '')
  655.                     else:
  656.                         position += 1
  657.                 
  658.             last = current
  659.             count += 1
  660.             ret = UFWRule.match(r, rule)
  661.             if ret < 1:
  662.                 matches += 1
  663.             
  664.             if ret == 0 and not found and not inserted:
  665.                 found = True
  666.                 if not rule.remove:
  667.                     newrules.append(rule)
  668.                 
  669.             rule.remove
  670.             if ret < 0 and not (rule.remove) and not inserted:
  671.                 found = True
  672.                 modified = True
  673.                 newrules.append(rule)
  674.                 continue
  675.             newrules.append(r)
  676.         
  677.         if inserted:
  678.             if matches > 0:
  679.                 rstr = _('Skipping inserting existing rule')
  680.                 if rule.v6:
  681.                     rstr += ' (v6)'
  682.                 
  683.                 return rstr
  684.         elif not found and not (rule.remove):
  685.             newrules.append(rule)
  686.         
  687.         if not found and rule.remove and not (self.dryrun):
  688.             rstr = _('Could not delete non-existent rule')
  689.             if rule.v6:
  690.                 rstr += ' (v6)'
  691.             
  692.             return rstr
  693.         if found and not (rule.remove) and not modified:
  694.             rstr = _('Skipping adding existing rule')
  695.             if rule.v6:
  696.                 rstr += ' (v6)'
  697.             
  698.             return rstr
  699.         
  700.         try:
  701.             self._write_rules(rule.v6)
  702.         except Exception:
  703.             None if rule.v6 else not (self.dryrun)
  704.             None if rule.v6 else not (self.dryrun)
  705.             err_msg = _("Couldn't update rules file")
  706.             UFWError(err_msg)
  707.         except:
  708.             None if rule.v6 else not (self.dryrun)
  709.  
  710.         rstr = _('Rules updated')
  711.         if rule.v6:
  712.             rstr = _('Rules updated (v6)')
  713.         
  714.         if self._is_enabled() and not (self.dryrun):
  715.             flag = ''
  716.             if modified and self._need_reload(rule.v6) or inserted:
  717.                 rstr = _('Rule ')
  718.                 if inserted:
  719.                     rstr += _('inserted')
  720.                 else:
  721.                     rstr += _('updated')
  722.                 if rule.v6:
  723.                     rstr += ' (v6)'
  724.                 
  725.                 if allow_reload:
  726.                     
  727.                     try:
  728.                         self._reload_user_rules()
  729.                     except Exception:
  730.                         raise 
  731.                     except:
  732.                         None<EXCEPTION MATCH>Exception
  733.                     
  734.  
  735.                 None<EXCEPTION MATCH>Exception
  736.                 rstr += _(' (skipped reloading firewall)')
  737.             elif found and rule.remove:
  738.                 flag = '-D'
  739.                 rstr = _('Rule deleted')
  740.             elif not found and not modified and not (rule.remove):
  741.                 flag = '-A'
  742.                 rstr = _('Rule added')
  743.             
  744.             if flag != '':
  745.                 exe = 'iptables'
  746.                 chain_prefix = 'ufw'
  747.                 if rule.v6:
  748.                     exe = 'ip6tables'
  749.                     chain_prefix = 'ufw6'
  750.                     rstr += ' (v6)'
  751.                 
  752.                 chain = chain_prefix + '-user-input'
  753.                 err_msg = _('Could not update running firewall')
  754.                 (rc, out) = cmd([
  755.                     exe,
  756.                     '-L',
  757.                     chain,
  758.                     '-n'])
  759.                 if rc != 0:
  760.                     raise UFWError(err_msg)
  761.                 rc != 0
  762.                 rule_str = '%s %s %s' % (flag, chain, rule.format_rule())
  763.                 pat_log = re.compile('(-A +)(ufw6?-user-[a-z\\-]+)(.*)')
  764.                 for s in self._get_lists_from_formatted(rule_str, chain_prefix):
  765.                     (rc, out) = cmd([
  766.                         exe] + s)
  767.                     if rc != 0:
  768.                         msg(out, sys.stderr)
  769.                         UFWError(err_msg)
  770.                     
  771.                     if flag == '-A' and pat_log.search(' '.join(s)):
  772.                         c = pat_log.sub('\\2', ' '.join(s))
  773.                         (rc, out) = cmd([
  774.                             exe,
  775.                             '-D',
  776.                             c,
  777.                             '-j',
  778.                             'RETURN'])
  779.                         if rc != 0:
  780.                             debug('FAILOK: ' + err_msg)
  781.                         
  782.                     rc != 0
  783.                 
  784.             
  785.         
  786.         return rstr
  787.  
  788.     
  789.     def get_app_rules_from_system(self, template, v6):
  790.         '''Return a list of UFWRules from the system based on template rule'''
  791.         rules = []
  792.         app_rules = []
  793.         if v6:
  794.             rules = self.rules6
  795.         else:
  796.             rules = self.rules
  797.         norm = template.dup_rule()
  798.         norm.set_v6(v6)
  799.         norm.normalize()
  800.         tuple = norm.get_app_tuple()
  801.         for r in rules:
  802.             tmp = r.dup_rule()
  803.             tmp.normalize()
  804.             tmp_tuple = tmp.get_app_tuple()
  805.             if tmp_tuple == tuple:
  806.                 app_rules.append(tmp)
  807.                 continue
  808.         
  809.         return app_rules
  810.  
  811.     
  812.     def _chain_cmd(self, chain, args, fail_ok = False):
  813.         '''Perform command on chain'''
  814.         exe = 'iptables'
  815.         if chain.startswith('ufw6'):
  816.             exe = 'ip6tables'
  817.         
  818.         (rc, out) = cmd([
  819.             exe] + args)
  820.         if rc != 0:
  821.             err_msg = _("Could not perform '%s'") % args
  822.             if fail_ok:
  823.                 debug('FAILOK: ' + err_msg)
  824.             else:
  825.                 raise UFWError(err_msg)
  826.         fail_ok
  827.  
  828.     
  829.     def update_logging(self, level):
  830.         '''Update loglevel of running firewall'''
  831.         if not self._is_enabled():
  832.             return None
  833.         if level not in self.loglevels.keys():
  834.             err_msg = _("Invalid log level '%s'") % level
  835.             raise UFWError(err_msg)
  836.         level not in self.loglevels.keys()
  837.         err_msg = _('Could not update running firewall')
  838.         for c in self.chains['before'] + self.chains['user'] + self.chains['after'] + self.chains['misc']:
  839.             
  840.             try:
  841.                 self._chain_cmd(c, [
  842.                     '-L',
  843.                     c,
  844.                     '-n'])
  845.             continue
  846.             raise UFWError(err_msg)
  847.             continue
  848.  
  849.         
  850.         
  851.         try:
  852.             for c in self.chains['before'] + self.chains['after'] + self.chains['misc']:
  853.                 self._chain_cmd(c, [
  854.                     '-F',
  855.                     c])
  856.                 self._chain_cmd(c, [
  857.                     '-Z',
  858.                     c])
  859.         except:
  860.             raise UFWError(err_msg)
  861.  
  862.         if level == 'off':
  863.             for c in self.chains['user']:
  864.                 self._chain_cmd(c, [
  865.                     '-D',
  866.                     c,
  867.                     '-j',
  868.                     'RETURN'], fail_ok = True)
  869.                 self._chain_cmd(c, [
  870.                     '-I',
  871.                     c,
  872.                     '-j',
  873.                     'RETURN'])
  874.             
  875.             return None
  876.         for c in self.chains['user']:
  877.             self._chain_cmd(c, [
  878.                 '-D',
  879.                 c,
  880.                 '-j',
  881.                 'RETURN'], fail_ok = True)
  882.         
  883.         limit_args = [
  884.             '-m',
  885.             'limit',
  886.             '--limit',
  887.             '3/min',
  888.             '--limit-burst',
  889.             '10']
  890.         if self.loglevels[level] >= self.loglevels['low']:
  891.             largs = []
  892.             if self.loglevels[level] < self.loglevels['high']:
  893.                 largs = limit_args
  894.             
  895.             for c in self.chains['after']:
  896.                 for t in [
  897.                     'input',
  898.                     'output',
  899.                     'forward']:
  900.                     if c.endswith(t):
  901.                         if self.get_default_policy(t) == 'reject' or self.get_default_policy(t) == 'deny':
  902.                             msg = '[UFW BLOCK] '
  903.                             
  904.                             try:
  905.                                 self._chain_cmd(c, [
  906.                                     '-A',
  907.                                     c,
  908.                                     '-j',
  909.                                     'LOG',
  910.                                     '--log-prefix',
  911.                                     msg] + largs)
  912.                             raise 
  913.  
  914.                         elif self.loglevels[level] >= self.loglevels['medium']:
  915.                             msg = '[UFW ALLOW] '
  916.                             
  917.                             try:
  918.                                 self._chain_cmd(c, [
  919.                                     '-A',
  920.                                     c,
  921.                                     '-j',
  922.                                     'LOG',
  923.                                     '--log-prefix',
  924.                                     msg] + largs)
  925.                             raise 
  926.  
  927.                         
  928.                     self.get_default_policy(t) == 'deny'
  929.                 
  930.             
  931.             largs = []
  932.             if self.loglevels[level] < self.loglevels['high']:
  933.                 largs = limit_args
  934.             
  935.             for c in self.chains['misc']:
  936.                 if c.endswith('allow'):
  937.                     msg = '[UFW ALLOW] '
  938.                 elif c.endswith('deny'):
  939.                     msg = '[UFW BLOCK] '
  940.                     if self.loglevels[level] >= self.loglevels['medium']:
  941.                         
  942.                         try:
  943.                             self._chain_cmd(c, [
  944.                                 '-I',
  945.                                 c,
  946.                                 '-m',
  947.                                 'state',
  948.                                 '--state',
  949.                                 'INVALID',
  950.                                 '-j',
  951.                                 'RETURN'] + largs)
  952.                         raise 
  953.  
  954.                     
  955.                 
  956.                 
  957.                 try:
  958.                     self._chain_cmd(c, [
  959.                         '-A',
  960.                         c,
  961.                         '-j',
  962.                         'LOG',
  963.                         '--log-prefix',
  964.                         msg] + largs)
  965.                 continue
  966.                 raise 
  967.                 continue
  968.  
  969.             
  970.         
  971.         if self.loglevels[level] >= self.loglevels['medium']:
  972.             largs = []
  973.             if self.loglevels[level] < self.loglevels['full']:
  974.                 largs = limit_args
  975.             
  976.             if self.loglevels[level] < self.loglevels['high']:
  977.                 largs = [
  978.                     '-m',
  979.                     'state',
  980.                     '--state',
  981.                     'NEW'] + limit_args
  982.             
  983.             msg = '[UFW AUDIT] '
  984.             for c in self.chains['before']:
  985.                 
  986.                 try:
  987.                     self._chain_cmd(c, [
  988.                         '-I',
  989.                         c,
  990.                         '-j',
  991.                         'LOG',
  992.                         '--log-prefix',
  993.                         msg] + largs)
  994.                 continue
  995.                 raise UFWError(err_msg)
  996.                 continue
  997.  
  998.             
  999.         
  1000.  
  1001.  
  1002.